package com.yl.util;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.yl.constant.Const;
import com.yl.constant.TimeUnit;

public class DtUtil {

    /**
     * 获取数据间隔，时间不分先后
     *
     * @param dt influxdb查询出来的时间字符串，例如：2022-09-15T16:00:00+08:00
     */
    public static long microTs(String dt) {
        return DateUtil.offsetHour(DateUtil.parse(dt), 8).getTime() * 1000;
    }

    /**
     * 获取数据间隔，时间不分先后
     *
     * @param ts1 这次时间戳
     * @param ts2 上次时间戳
     */
    public static long diffTime(long ts1, long ts2) {
        return diffTime(DateUtil.date(ts1), DateUtil.date(ts2), TimeUnit.S);
    }

    /**
     * 获取数据间隔，时间不分先后
     *
     * @param dt1      时间参数1
     * @param dt2      时间参数2
     * @param timeUnit 时间单位
     */
    public static long diffTime(DateTime dt1, DateTime dt2, TimeUnit timeUnit) {
        if (TimeUnit.S.equals(timeUnit)) {
            return DateUtil.between(dt1, dt2, DateUnit.SECOND);
        } else if (TimeUnit.M.equals(timeUnit)) {
            return DateUtil.between(dt1, dt2, DateUnit.MINUTE);
        } else if (TimeUnit.H.equals(timeUnit)) {
            return DateUtil.between(dt1, dt2, DateUnit.HOUR);
        } else if (TimeUnit.D.equals(timeUnit)) {
            return DateUtil.between(dt1, dt2, DateUnit.DAY);
        } else {
            return -1;
        }
    }

    /**
     * 根据指定时间单位解析带单位的时间
     *
     * @param timeWithUnit 带单位的时间，例：1d
     * @param unit         时间单位
     */
    public static long getTime(String timeWithUnit, TimeUnit unit) {
        for (TimeUnit timeUnit : TimeUnit.values()) {
            String tag = timeUnit.getTag();
            if (timeWithUnit.contains(tag)) {
                int time = Integer.parseInt(timeWithUnit.replace(tag, Const.PTN_EMPTY));
                TimeUnit fromUnit = TimeUnit.get(tag);
                if (null != fromUnit) {
                    int convertRatio = getConvertRatio(fromUnit, unit);
                    return (long) time * convertRatio;
                }
            }
        }
        return 0;
    }

    /**
     * 获取把源时间单位转换成目标时间单位的转换系数
     *
     * @param fromUnit 源时间单位
     * @param toUnit   目标时间单位
     * @return 返回转换系数
     */
    private static int getConvertRatio(TimeUnit fromUnit, TimeUnit toUnit) {
        return fromUnit.getRatio() / toUnit.getRatio();
    }

    /**
     * 把16位微秒时间戳转换成标准时间，精确到指定单位
     *
     * @param microTs  微秒级时间戳
     * @param timeUnit 时间单位
     */
    public static String toDateStart(Long microTs, TimeUnit timeUnit) {
        DateTime dt = DateUtil.date(microTs / 1000);
        if (TimeUnit.S.equals(timeUnit)) {
            return dt.toString();
        } else if (TimeUnit.M.equals(timeUnit)) {
            return DateUtil.beginOfMinute(dt).toString();
        } else if (TimeUnit.H.equals(timeUnit)) {
            return DateUtil.beginOfHour(dt).toString();
        } else if (TimeUnit.D.equals(timeUnit)) {
            return DateUtil.beginOfDay(dt).toString();
        } else {
            return null;
        }
    }

    /**
     * 把微秒格式的时间字符串解析成16位微秒时间戳【原始数据时间解析】
     *
     * @param dateStr 微秒格式的时间字符串【yyyyMMddHHmmssSSSSSS】
     * @return 返回16位微秒时间戳
     */
    public static long parseDateStr(String dateStr) {
        int length = dateStr.length();
        String s1 = dateStr.substring(0, length - 3);
        String s2 = dateStr.substring(length - 3, length);
        long ms = DateUtil.parse(s1, Const.FMT_TRIM_MILLI).getTime();
        return ms * 1000 + Integer.parseInt(s2);
    }

}
